# Cria o codigo em java para a funcao carregaMicroInstrucoes
# Cria o codigo em java para a funcao carregaInstrucoes
# Cria o codigo em java para o parser

# Utiliza dois arquivo principais:
#    micros.txt: contem as micros e os pontos de controle que devem ser setados de acordo com a instrucao (devem ser feitos a mao)
#    instrucoes.txt: contem as instrucoes e suas micros. Arquivo gerado pelo script parser.py

import sys

dic_micro = {}
dic_instrucao = {}

class Instrucao:
    def __init__(self, nome, micros):
        self.nome_cru = nome.replace(" ","")
        self.nome = nome
        self.micros = micros
        self.codigo = None


    def geraCodigo(self):
        return 'instrucao.put("%s", new Instrucao("%s", "%s"));' % (self.nome_cru, self.codigo, self.nome)        

class MicroInstrucao:
    def __init__(self, i, nome, t1, t2, t3):
        self.posicao = i
        self.nome = filtroNome(nome)
        self.t1 = self.filtroTn(t1)
        self.t2 = self.filtroTn(t2)
        self.t3 = self.filtroTn(t3)

    def geraCodigo(self):
        return 'microInstrucoes[%d] = new MicroInstrucao("%s", "%s", "%s", "%s");' % (self.posicao, self.nome, self.t1, self.t2, self.t3)

    def filtroNome(string):
        string = string.replace("\n", "").replace("\t", "")
        string = string.split(" ")
        r = ''
        for c in string:
            if c != '':
                r = r + c + ' '
        return r

    def filtroTn(self, tn):
        return tn.replace("-", "").replace(" ", "").replace("\n", "").replace("\t", "")

def carregaMicroinstrucoes(file_name):
    global dic_micro

    file = open(file_name)
    lines = file.readlines()
    file.close()

    i, n = 0, 1
    while i < len(lines):
        nome = lines[i]
        t1 = lines[i+1]
        t2 = lines[i+2]
        t3 = lines[i+3]

        micro = MicroInstrucao(n, nome, t1, t2, t3)
        if (micro.nome == 'Rinst <- Rdados '):
            micro.posicao = 0
            n -= 1
        dic_micro[micro.nome] = micro

        i, n = i+5, n+1


def geraEnd():
    global dic_instrucao

    dic = {}
    cod = 1
    for k in dic_instrucao.keys():
        x = bin(cod)[2:]
        x = (20 - len(x))*'0' + x
        
        dic_instrucao[k].codigo = x
        cod += 1

def filtroNome(string):
    string = string.replace("\n", "").replace("\t", "")
    string = string.split(" ")
    r = ''
    for c in string:
        if c != '':
            r = r + c + ' '
    return r
    
def carregaInstrucoes(file_name):
    global dic_instrucao

    file = open(file_name)
    lines = file.readlines()
    file.close()

    i, n = 0, 0
    while i < len(lines):       
        nome = filtroNome(lines[i])
        micros = []
        i += 1

        if i >= len(lines): break

        while lines[i].replace(" ", "").replace("\n", "").replace("\t", "") != "":
            lines[i] = filtroNome(lines[i])
            micros.append(lines[i])
            i += 1

            if i >= len(lines): break

        i += 1        
        
        instrucao = Instrucao(nome, micros)
        dic_instrucao[nome] = instrucao
    geraEnd()

def criaHashMap(value, start='0'):
    
    def geraCodigo(chave, valor):
        return '%s,%d' % (chave, valor)
        

    global dic_micro
    global dic_instrucao

    file = open('saida/[' + value + ' - JAVA]sequenciaMicroinstrucoes - Gerador de Endereco.txt', 'w')
    inst_keys = dic_instrucao.keys()
    inst_keys.sort()
    for inst_key in inst_keys:
        file.write('%s:' % (dic_instrucao[inst_key].codigo))
        for nome_micro in dic_instrucao[inst_key].micros:
            micro = dic_micro[nome_micro]
            #file.write(geraCodigo(dic_instrucao[inst_key].codigo + str(end_ult_micro), micro.posicao))
            #file.write('\n')
            file.write('%d ' % (micro.posicao))
            #print geraCodigo(dic_instrucao[inst_key].codigo + str(end_ult_micro), micro.posicao)
            #end_ult_micro = micro.posicao
        file.write('\n')
    file.close()
            
        
    

def main(value):
    global dic_micro
    global dic_instrucao

    carregaMicroinstrucoes('pasta_aux/[' + value + ']microinstrucoes.txt')
    carregaInstrucoes('pasta_aux/[' + value + ']instrucoes.txt')

    file = open('saida/[' + value + ' - JAVA]microinstrucoes - Memoria de Controle.txt', 'w')
    print "-"*20, "Codigo das MicroInstrucoes"
    keys = dic_micro.keys()
    keys.sort()
    for micro in keys:
        file.write(dic_micro[micro].geraCodigo())
        file.write('\n')
        print dic_micro[micro].geraCodigo()
    print "\n\n", "-"*20, "\n"
    file.close()
    print "-"*20, "Codigo das Instrucoes"
    file = open('saida/[' + value + ' - JAVA]instrucoes - Parser.txt', 'w')
    keys = dic_instrucao.keys()
    keys.sort()
    for micro in keys:
        file.write(dic_instrucao[micro].geraCodigo())
        file.write('\n')
        print dic_instrucao[micro].geraCodigo()
    print "\n\n", "-"*20, "\n"
    file.close()
    print "-"*20, "Codigo Hash Map"
    print value
    criaHashMap(value)





if __name__ == '__main__':
    value = ""

    if len(sys.argv) > 1:
        value = sys.argv[1]

    main(value)

        

        
